package ioc

import (
	"context"
	"database/sql"
	"fmt"
	"gitee.com/DonHz/basic-go/webook/internal/repository/dao"
	"gitee.com/DonHz/basic-go/webook/pkg/logger"
	"github.com/spf13/viper"
	"gorm.io/driver/mysql"
	"gorm.io/gorm"
	glogger "gorm.io/gorm/logger"
	"log"
	"time"
)

func InitDB(l logger.Logger) *gorm.DB {
	// 在初始化过程中读取配置文件
	type Config struct {
		DSN string `yaml:"dsn"`
	}
	var cfg Config = Config{
		DSN: "root:123456@tcp(localhost:3306)/mysql",
	}
	err:=viper.UnmarshalKey("db", &cfg)
	dsn:=viper.GetString("db")
	fmt.Println(dsn)
	if err!=nil {
		fmt.Println(29, err)
		panic(any(err))
	}
	db, err := gorm.Open(mysql.Open(cfg.DSN), &gorm.Config{
		Logger: glogger.New(gormLoggerFunc(l.Debug), glogger.Config{
			// 慢查询阈值，50ms或100ms，SQL查询必然要求命中索引，最好走一次磁盘IO，不超过10ms
			SlowThreshold: time.Millisecond * 10,
			IgnoreRecordNotFoundError: false,
			LogLevel: glogger.Info,
		}),
	})
	fmt.Println("mysql.dsn: ", cfg.DSN)
	//db, err := gorm.Open(mysql.Open(config.Config.DB.DSN))
	//fmt.Println(config.Config.DB.DSN)
	if err != nil {
		// 初始化出错，应用就不要启动了
		panic(err.(any))
	}
	// 自动迁移，确保数据库表格与结构同步。它会创建新表、添加缺失的列和索引，但不会删除多余列以保护数据
	err = dao.InitTables(db)
	if err != nil {
		panic(err.(any))
	}
	return db
}

type gormLoggerFunc func(msg string, args ...logger.Field)

func (g gormLoggerFunc) Printf(msg string, args ...interface{} ){
	g(msg, logger.Field{Key: "args", Value: args})
}

var db *gorm.DB

func InitTestDB() *gorm.DB {
	if db == nil{
		dsn:="root:123456@tcp(localhost:3306)/mysql"
		sqlDB, err:=sql.Open("mysql", dsn)
		if err!=nil{
			panic(any(err))
		}
		for {
			ctx, cancel:=context.WithTimeout(context.Background(), time.Second*2)
			err = sqlDB.PingContext(ctx)
			cancel()
			if err==nil{
				break
			}
			log.Println("等待连接MySQL", err)
		}
		db, err := gorm.Open(mysql.Open(dsn))
		if err!=nil{
			panic(any(err))
		}
		err = dao.InitTables(db)
		if err!=nil{
			panic(any(err))
		}
	}
	return db
}